<?php
/**
* Classe Formulaire.
*
* PHP version 5.1.6
*
* @package   Smartbok
* @author    Christophe Hebet <christophe.hebet@dgfip.finances.gouv.fr>
* @copyright 2013 - DGFiP
*/

class SmartbokFormulaire {

    /**
     * liste d'objet champ
     * @var array
     */
    private $_champs;

    /**
     * Méthode d'ajout d'un objet champ à la liste des éléments du formulaire
     * Le paramètre peut être :
     * une array contenant tout ou partie des attributs de l'objet champ (dans l'ordre de la déclaration de la classe)
     * Une array indicé avec les noms des attributs et leur valeur
     * un objet champ.
     */
    public function ajouterChamp($params) {
        if (is_a($params, 'SmartbokChamp') === true) {
            $this->_champs[] = $params;
        }
        else {
            $champ = new SmartbokChamp($params);
            $this->_champs[] = $champ;
        }
    }

    /**
     * Méthode d'ajout du type d'encodage au formulaire si précisé. Modifie le code html du template et le retourne
     * @param string $htmlTemplate
     * @return string
     */
    public static function ajouterEncodageFormulaire($htmlTemplate) {

        return $htmlTemplate;
    }

    /**
     * Méthode d'inhjection des données postées dans les objets champs du formulaire
     */
    private function injecterDonnees() {
        foreach ($this->_champs as &$champ) {
            if (isset($_POST[$champ->getValue('_name')]) === true) {
                $champ->modifierChamp('_valeur', $_POST[$champ->getValue('_name')]);
            }
        }
    }

    /**
     * méthode qui permet d'ajouter un controle à un champ
     * @param string $nomChamp
     * @param integer $controle
     * @param array $listeParam
     */
    public function ajouterControleChamp($nomChamp, $controle, $listeParam= null) {
        foreach ($this->_champs as &$champ) {
            if ($champ->getValue('_name') === $nomChamp) {
               $champ->ajouterControle($controle, $listeParam);
               break;
            }
        }
    }

    /**
     * méthode qui permet d'ajouter un controle applicatif à un champ. ce controle peut être une fonction ou
     * une méthode d'un objet. Les messages d'anomalie doivent être pris en charge par la fonction de
     * controle applicatif (pas de gestion du message pris en charge dans smartbok autrement)
     *
     * @param string $nomChamp
     * @param string $controle
     * @param string|array $params
     * @param string $objet
     */
    public function ajouterControleApplicatif($nomChamp, $controle, $params= null, &$objet= null)
    {
        foreach ($this->_champs as &$champ) {
            if ($champ->getValue('_name') === $nomChamp) {
                $champ->ajouterControleApplicatif($controle, $params, $objet);
                break;
            }
        }
    }

    /**
     * Méthode qui permet de modifier le libellé d'un message d'erreur pour un champ donné.
     * le libelle peut contenir un des tags suivant pour être remplacé par la valeur correspondante
     * #NOMCHAMP#, #PARAM#, #VALEUR#
     *
     * @param integer $type constante de la classe SmartbokChamp
     * @param string $message
     */
    public function modifierLibelleMessageErreur($nomChamp, $type, $message) {
        foreach ($this->_champs as &$champ) {
            if ($champ->getValue('_name') === $nomChamp) {
                $champ->modifierMessageErreur($type, $message);
                break;
            }
        }
    }

    /**
     * méthode d'ajout de valeur autorisées à un champ. les valeurs passées en paramètre peuvent l'être sous la forme
     * de chaine ou de tableau (array). Si une chaine est passée en aprmaètyre elle est considérée comme une valeur
     * unique.
     * @param string $nomChamp nom du champ dans le formulaire html
     * @param string|array $valeurs
     */
    public function ajouterListeValeurChamp($nomChamp, $valeurs) {
        foreach ($this->_champs as &$champ) {
            if ($champ->getValue('_name') === $nomChamp) {
                $champ->ajouterListeValeurAutorisees($valeurs);
                break;
            }
        }
    }

    /**
     * Méthode de contrôle du formulaire. La méthode boucle sur la collection de champs et effectue tous les contrôles
     * associés aux champs. La méthode contrôle également la présence du jeton csrf et contrôle celui-ci.
     * la méthjode renvoie true si tous les controles sont positifs. Elle retourne une array contenant le nom des champs
     * en erreur en cas d'echec d'un controle
     *
     * @return
     */
    public function controlerFormulaire() {
        if (count($_POST) > 0) {
            $this->injecterDonnees();
            foreach ($this->_champs as $champ) {
                $controle =  $champ->controler();
                if ($controle === false) {
                    $ano[] = $nomChamp = $champ->getValue('_id');
                }
            }
            if (isset($_POST['jetonCsrf']) === true) {
                if ($_POST['jetonCsrf'] !== $_SESSION['Csrf']['jeton']) {
                    SmartbokMessage::addMessage(SmartbokMessage::ERR, 'Le formulaire n\'est pas valide');
                    $ano[] = 'jetonCsrf';
                }
            }
        }
        if (isset($ano)) {
            return $ano;
        }
        return true;
    }
}